#include "AES.h"
#include "TestBase.h"

TestBase::TestBase()
{
	info.Name = "CryptoSystem Test 0 - AES";
	info.Category = 0x3100;
	info.CategoryName = "CryptoSystem";
	info.File = __FILE__;
}

bool TestBase::Run()
{
	unsigned char key[16] = { // 000102030405060708090a0b0c0d0e0f
		0x00, 0x01, 0x02, 0x03,
		0x04, 0x05, 0x06, 0x07,
		0x08, 0x09, 0x0a, 0x0b,
		0x0c, 0x0d, 0x0e, 0x0f
	};
	unsigned char plain1[16] = { // 00112233445566778899aabbccddeeff
		0x00, 0x11, 0x22, 0x33,
		0x44, 0x55, 0x66, 0x77,
		0x88, 0x99, 0xaa, 0xbb,
		0xcc, 0xdd, 0xee, 0xff
	};
	unsigned char cipher1[16] = { // 69c4e0d86a7b0430d8cdb78070b4c55a
		0x69, 0xc4, 0xe0, 0xd8,
		0x6a, 0x7b, 0x04, 0x30,
		0xd8, 0xcd, 0xb7, 0x80,
		0x70, 0xb4, 0xc5, 0x5a
	};
	unsigned char cipher2[16];
	unsigned char plain2[16]; // 00112233445566778899aabbccddeeff
	int fail = 0, i = 0;
	StateAES state;
	AES_Init(&state, key);
	AES_Encrypt(&state, plain1);
	AES_Final(&state, cipher2);
	for (i = 0; i < 16; i ++)
	{
		if (cipher1[i] != cipher2[i])
		{
			fail = 1;
		}
	}
	if (fail != 0)
	{
		std::cout << GetTestInfo()->Name << " encryption failure info" << std::endl;
		printf("Output          : %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n", (int)(cipher2[0]), (int)(cipher2[1]), (int)(cipher2[2]), (int)(cipher2[3]), (int)(cipher2[4]), (int)(cipher2[5]), (int)(cipher2[6]), (int)(cipher2[7]));
		printf("                : %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n", (int)(cipher2[8]), (int)(cipher2[9]), (int)(cipher2[10]), (int)(cipher2[11]), (int)(cipher2[12]), (int)(cipher2[13]), (int)(cipher2[14]), (int)(cipher2[15]));
		printf("Expected output : %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n", (int)(cipher1[0]), (int)(cipher1[1]), (int)(cipher1[2]), (int)(cipher1[3]), (int)(cipher1[4]), (int)(cipher1[5]), (int)(cipher1[6]), (int)(cipher1[7]));
		printf("                : %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n", (int)(cipher1[8]), (int)(cipher1[9]), (int)(cipher1[10]), (int)(cipher1[11]), (int)(cipher1[12]), (int)(cipher1[13]), (int)(cipher1[14]), (int)(cipher1[15]));
		return false;
	}
	AES_Init(&state, key);
	AES_Decrypt(&state, cipher1);
	AES_Final(&state, plain2);
	for (i = 0; i < 16; i ++)
	{
		if (plain1[i] != plain2[i])
		{
			fail = 1;
		}
	}
	if (fail != 0)
	{
		std::cout << GetTestInfo()->Name << " decryption failure info" << std::endl;
		printf("Output          : %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n", (int)(plain2[0]), (int)(plain2[1]), (int)(plain2[2]), (int)(plain2[3]), (int)(plain2[4]), (int)(plain2[5]), (int)(plain2[6]), (int)(plain2[7]));
		printf("                : %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n", (int)(plain2[8]), (int)(plain2[9]), (int)(plain2[10]), (int)(plain2[11]), (int)(plain2[12]), (int)(plain2[13]), (int)(plain2[14]), (int)(plain2[15]));
		printf("Expected output : %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n", (int)(plain1[0]), (int)(plain1[1]), (int)(plain1[2]), (int)(plain1[3]), (int)(plain1[4]), (int)(plain1[5]), (int)(plain1[6]), (int)(plain1[7]));
		printf("                : %.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x\n", (int)(plain1[8]), (int)(plain1[9]), (int)(plain1[10]), (int)(plain1[11]), (int)(plain1[12]), (int)(plain1[13]), (int)(plain1[14]), (int)(plain1[15]));
		return false;
	}
	return true;
}